//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package utils

import (
	"context"
	"sync"

	"atomgit.com/openlinksaas-org/api-server/dao"
)

type _KeywordItem struct {
	head        rune
	keywordList [][]rune
}

var keywordMap map[rune]*_KeywordItem = map[rune]*_KeywordItem{}
var keywordLock sync.RWMutex
var keywordVersion = uint32(0)

func loadKeyword(ctx context.Context) error {
	keywordLock.Lock()
	defer keywordLock.Unlock()

	versionItem, err := dao.VersionDao.Get(ctx, dao.VERSION_KEY_KEYWORD)
	if err != nil {
		return err
	}
	if versionItem.Version == keywordVersion {
		return nil
	}
	keywordist, err := dao.KeywordDao.DistinctKeyword(ctx)
	if err != nil {
		return err
	}
	tmpMap := map[rune]*_KeywordItem{}
	for _, keyword := range keywordist {
		if len(keyword) == 0 {
			continue
		}
		head := []rune(keyword)[0]
		cacheItem, ok := tmpMap[head]
		if !ok {
			cacheItem = &_KeywordItem{
				head:        head,
				keywordList: [][]rune{},
			}
		}
		cacheItem.keywordList = append(cacheItem.keywordList, []rune(keyword))
		tmpMap[head] = cacheItem
	}
	keywordMap = tmpMap
	keywordVersion = versionItem.Version
	return nil
}

func CheckKeyWrod(ctx context.Context, content string) ([]string, error) {
	err := loadKeyword(ctx)
	if err != nil {
		return nil, err
	}

	keywordLock.RLock()
	defer keywordLock.RUnlock()

	tmpMap := map[string]bool{}

	contentData := []rune(content)
	contentLen := len(contentData)
	for index, c := range contentData {
		cacheItem, ok := keywordMap[c]
		if !ok {
			continue
		}
		for _, cmpValue := range cacheItem.keywordList {
			cmpValueLen := len(cmpValue)
			if index+cmpValueLen > contentLen {
				continue
			}
			match := true
			for i, cmpCahr := range cmpValue {
				if contentData[index+i] != cmpCahr {
					match = false
					break
				}
			}
			if match {
				tmpMap[string(cmpValue)] = true
			}
		}
	}
	retList := []string{}
	for value := range tmpMap {
		retList = append(retList, value)
	}
	return retList, nil
}
